package svg;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import util.IDs;
import util.NameValueParser;
import util.PAGColor;
import util.Petal;
import util.Star;

/**
 * This class is used to manipulate the board svg.
 */
public class BoardAdapter {
	
	private Document _doc;
	private NameValueParser _nameValueParser;
	
	/**
	 * Creates a new board adapter.
	 * 
	 * @param doc the document which represents the SVG
	 */
	public BoardAdapter(Document doc) {
		_doc = doc;
		setSplashScreenVisible(false);
		setTextColor();
		eraseAllPetals();
		eraseAllStars();
	}
	
	/**
	 * Sets the color of the text.
	 */
	private void setTextColor() {
		Element txt = _doc.getElementById(IDs.TXT_COLOR_1.toString());
		Node n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.RED);
		txt.getChildNodes().item(0).setTextContent("Red: 1");
		
		txt = _doc.getElementById(IDs.TXT_COLOR_2.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.GREEN);
		txt.getChildNodes().item(0).setTextContent("Green: 2");

		txt = _doc.getElementById(IDs.TXT_COLOR_3.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.BLUE);
		txt.getChildNodes().item(0).setTextContent("Blue: 3");
		
		txt = _doc.getElementById(IDs.TXT_COLOR_4.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.ORANGE);
		txt.getChildNodes().item(0).setTextContent("Orange: 4");
		
		txt = _doc.getElementById(IDs.TXT_COLOR_5.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.PURPLE);
		txt.getChildNodes().item(0).setTextContent("Purple: 5");
		
		txt = _doc.getElementById(IDs.TXT_COLOR_6.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.CYAN);
		txt.getChildNodes().item(0).setTextContent("Cyan: 6");
		
		txt = _doc.getElementById(IDs.TXT_COLOR_7.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.GREY);
		txt.getChildNodes().item(0).setTextContent("Grey: 7");
		
		txt = _doc.getElementById(IDs.TXT_COLOR_8.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.PINK);
		txt.getChildNodes().item(0).setTextContent("Pink: 8");
		
		txt = _doc.getElementById(IDs.TXT_COLOR_9.toString());
		n = txt.getChildNodes().item(0).getAttributes().getNamedItem(IDs.STYLE.toString());
		n.setNodeValue(n.getNodeValue() + ";fill:#" + PAGColor.LIGHT_BLUE);
		txt.getChildNodes().item(0).setTextContent("Light-Blue: 9");
	}

	/**
	 * This method displays the given petal on the given position on the board.
	 * @param petal the petal including the color
	 * @param position the position 1 - 30
	 */
	public void setPetal(Petal petal, int position)
	{
		Element element = _doc.getElementById(IDs.PETAL.toString() + position);
		setShapeColor(element, petal.getColor());
	}
	
	/**
	 * This method displays the given star on the given position on the board. 
	 * @param star the star including its colors
	 * @param position the position 1 - 19
	 */
	public void setStar(Star star, int position)
	{
		Element center = _doc.getElementById(IDs.STAR.toString() + position + "center");
		Element a = _doc.getElementById(IDs.STAR.toString() + position + "a");
		Element b = _doc.getElementById(IDs.STAR.toString() + position + "b");
		Element c = _doc.getElementById(IDs.STAR.toString() + position + "c");
		Element d = _doc.getElementById(IDs.STAR.toString() + position + "d");
		Element e = _doc.getElementById(IDs.STAR.toString() + position + "e");
		Element f = _doc.getElementById(IDs.STAR.toString() + position + "f");
		
		setShapeColor(center, star.getCenterColor());
		setShapeColor(a, star.getVerticalColor());
		setShapeColor(b, star.getUpColor());
		setShapeColor(c, star.getDownColor());
		setShapeColor(d, star.getVerticalColor());
		setShapeColor(e, star.getUpColor());
		setShapeColor(f, star.getDownColor());
	}
	
	public void setStarShade(boolean visible, int position)
	{
		Element star = _doc.getElementById(IDs.STAR_SHADOW.toString() + position);
		Node n = (Node) _doc.createAttribute(IDs.DISPLAY.toString());
		if (visible)
		{
			n.setNodeValue(IDs.INLINE.toString());
		}
		else
		{
			n.setNodeValue(IDs.NONE.toString());
		}
		star.getAttributes().setNamedItem(n);
	}
	
	public void setStarShadeColor(PAGColor color, int position)
	{
		Element center = _doc.getElementById(IDs.STAR_SHADOW.toString() + position + "center");
		Element a = _doc.getElementById(IDs.STAR_SHADOW.toString() + position + "a");
		Element b = _doc.getElementById(IDs.STAR_SHADOW.toString() + position + "b");
		Element c = _doc.getElementById(IDs.STAR_SHADOW.toString() + position + "c");
		Element d = _doc.getElementById(IDs.STAR_SHADOW.toString() + position + "d");
		Element e = _doc.getElementById(IDs.STAR_SHADOW.toString() + position + "e");
		Element f = _doc.getElementById(IDs.STAR_SHADOW.toString() + position + "f");
		
		setShapeColor(center, color);
		setShapeColor(a, color);
		setShapeColor(b, color);
		setShapeColor(c, color);
		setShapeColor(d, color);
		setShapeColor(e, color);
		setShapeColor(f, color);
	}
	
	/**
	 * Sets the fill color of the given shape
	 * @param shape the shape
	 * @param color the color
	 */
	private void setShapeColor(Element shape, PAGColor color) {
		String value = shape.getAttributes().getNamedItem(IDs.STYLE.toString()).getNodeValue();
		_nameValueParser = new NameValueParser();
		_nameValueParser.parse(value);
		String newValue = _nameValueParser.setNameValue("fill", "#" + color.toString());
		shape.getAttributes().getNamedItem(IDs.STYLE.toString()).setNodeValue(newValue);
	}

	/**
	 * Sets the given star as the preview star. 
	 * @param star the star including its colors
	 */
	public void setPreviewStar(Star star) {
		setStar(star, 0);
	}
	
	/**
	 * Sets the actual score on the left side of the board. 
	 * @param score the score
	 */
	public void setScore(int score)
	{
		Element txtScore = _doc.getElementById(IDs.TXT_SCORE.toString());
		txtScore.setTextContent(String.valueOf(score));
	}

	/**
	 * Sets the final score. And displays the game over splash.
	 * @param score the score 
	 */
	public void setFinalScore(int score) {
		Element txtScore = _doc.getElementById(IDs.FINAL_SCORE.toString());
		txtScore.setTextContent(String.valueOf(score));
	
		setSplashScreenVisible(true);
	}

	/**
	 * Sets visibility of game over splash screen
	 * @param visible true sets the splash screen visible
	 */
	public void setSplashScreenVisible(boolean visible) {
		Element splash = _doc.getElementById(IDs.GAME_OVER_SPLASH.toString());
		Node n = (Node) _doc.createAttribute(IDs.DISPLAY.toString());
		if (visible)
		{
			n.setNodeValue(IDs.INLINE.toString());
		}
		else
		{
			n.setNodeValue(IDs.NONE.toString());
		}
		splash.getAttributes().setNamedItem(n);
	}

	/**
	 * Sets all stars on the board to grey again.
	 */
	public void eraseAllStars() {
		Star star = new Star();
		for (int i = 0; i < 20; i++)
		{
			setStar(star, i);
		}
	}

	/**
	 * Sets all petals on the board do grey again.
	 */
	public void eraseAllPetals() {
		Petal petal = new Petal(PAGColor.EMPTY);
		for (int i = 1; i < 31; i++)
		{
			setPetal(petal, i);
		}
	}
}
